package webbandidong.dao.impl;

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;
import webbandidong.dao.MobileDAO;
import webbandidong.model.Mobile;
import webbandidong.util.Constant;
import webbandidong.util.CustomHibernateDaoSupport;
import webbandidong.viewmodel.SearchMobileViewModel;

@Repository(value = "mobileDAOImpl")
public class MobileDAOImpl extends CustomHibernateDaoSupport implements MobileDAO {

    public List<Mobile> getAllMobiles() {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            String hql = "from Mobile order by name";
            Query query = session.createQuery(hql);
            List<Mobile> mobiles = (List<Mobile>) query.list();
            transaction.commit();
            return mobiles;
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return null;
            }
        }
        // Khong duoc dong session vi khong LAZY fetch duoc
    }

    public Mobile getMobileById(int id) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            String hql = "from Mobile where id = :id";
            Query query = session.createQuery(hql);
            query.setParameter("id", id);
            List<Mobile> mobiles = (List<Mobile>) query.list();
            transaction.commit();
            if (mobiles != null && !mobiles.isEmpty()) {
                return mobiles.get(0);
            }
            return null;
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return null;
            }
        }
    }

    public String addMobile(Mobile mobile) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.save(mobile);
            transaction.commit();
            return Constant.SUCCESS;
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return Constant.ERROR;
            }
        }
        finally {
            if (session != null) {
                session.close();
            }
        }
    }

    public String updateMobile(Mobile mobile) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.update(mobile);
            transaction.commit();
            return Constant.SUCCESS;
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return Constant.ERROR;
            }
        }
        finally {
            if (session != null) {
                session.close();
            }
        }
    }

    public String deleteMobile(Mobile mobile) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            session.delete(mobile);
            transaction.commit();
            return Constant.SUCCESS;
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return Constant.ERROR;
            }
        }
        finally {
            if (session != null) {
                session.close();
            }
        }
    }

    public List<Mobile> getMobilesCriteria(SearchMobileViewModel model, int page) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Mobile.class, "m");
            if (model.getMobileName() != null && !"".equals(model.getMobileName())) {
                criteria.add(Restrictions.like("name", "%" + model.getMobileName() + "%"));
            }
            if (model.getFromPrice() != null && !"".equals(model.getFromPrice())) {
                double fromPrice = Double.parseDouble(model.getFromPrice());
                criteria.add(Restrictions.ge("price", fromPrice));
            }
            if (model.getToPrice() != null && !"".equals(model.getToPrice())) {
                double toPrice = Double.parseDouble(model.getToPrice());
                criteria.add(Restrictions.le("price", toPrice));
            }
            if (model.getBeforeReleaseDate() != null) {
                criteria.add(Restrictions.ge("releaseDate", model.getBeforeReleaseDate()));
            }
            if (!"NONE".equals(model.getCompanyId())) {
                int companyId;
                try {
                    companyId = Integer.parseInt(model.getCompanyId());
                    criteria.setFetchMode("company", FetchMode.JOIN)
                            .add(Restrictions.eq("company.id", companyId));
                }
                catch (Exception ex) {
                    
                }
            }
            criteria.setMaxResults(Constant.PAGE_SIZE);
            criteria.setFirstResult((page - 1) * Constant.PAGE_SIZE);
            transaction.commit();
            return criteria.list();
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return null;
            }
        }
    }

    public List<Mobile> getMobilesCriteria(SearchMobileViewModel model) {
        Session session = null;
        Transaction transaction = null;

        try {
            session = getHibernateTemplate().getSessionFactory().openSession();
            transaction = session.beginTransaction();
            Criteria criteria = session.createCriteria(Mobile.class, "m");
            if (model.getMobileName() != null && !"".equals(model.getMobileName())) {
                criteria.add(Restrictions.like("name", "%" + model.getMobileName() + "%"));
            }
            if (model.getFromPrice() != null && !"".equals(model.getFromPrice())) {
                double fromPrice = Double.parseDouble(model.getFromPrice());
                criteria.add(Restrictions.ge("price", fromPrice));
            }
            if (model.getToPrice() != null && !"".equals(model.getToPrice())) {
                double toPrice = Double.parseDouble(model.getToPrice());
                criteria.add(Restrictions.le("price", toPrice));
            }
            if (model.getBeforeReleaseDate() != null) {
                criteria.add(Restrictions.ge("releaseDate", model.getBeforeReleaseDate()));
            }
            if (!"NONE".equals(model.getCompanyId())) {
                int companyId;
                try {
                    companyId = Integer.parseInt(model.getCompanyId());
                    criteria.setFetchMode("company", FetchMode.JOIN)
                            .add(Restrictions.eq("company.id", companyId));
                }
                catch (Exception ex) {

                }
            }
            transaction.commit();
            return criteria.list();
        }
        catch (Exception ex) {
            try {
                transaction.rollback();
            }
            finally {
                return null;
            }
        }
    }
}
